package com.tangsm.spring.boot.filter.common.config;

import com.google.common.collect.Maps;
import com.tangsm.spring.boot.filter.common.filter.ConfigRegisterFilter;
import com.tangsm.spring.boot.filter.common.filter.MyFilter;
import com.tangsm.spring.boot.filter.common.filter.XssAndSqlFilter;
import com.tangsm.spring.boot.filter.common.interceptor.MyInterceptor;
import com.tangsm.spring.boot.filter.common.listener.MyHttpRequestListener;
import com.tangsm.spring.boot.filter.common.listener.MyHttpSessionListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.Filter;
import java.util.EventListener;
import java.util.Map;

/**
 * 过滤器、拦截器、监听器注册
 *
 * @author tangsm
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private MyInterceptor myInterceptor;

    /**
     * 添加Spring MVC生命周期拦截器，用于控制器方法调用和资源处理程序请求的预处理和后处理。
     * 可以注册拦截器以应用于所有请求，或者限制于URL模式的一个子集。
     *
     * @param registry 拦截器注册
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor);
    }

    /**
     * 注册过滤器
     * <p>此注册方式同等于MyFilter类上使用以下两个注解：</p>
     * <p>@Component</p>
     * <p>@WebFilter(filterName = "myFilter", urlPatterns = "/*")</p>
     *
     * @return 过滤器
     */
    @Bean
    public FilterRegistrationBean<Filter> myFilter() {
        // 创建一个新的FilterRegistrationBean实例
        FilterRegistrationBean<Filter> filterRegistration = new FilterRegistrationBean<>();

        // 设置过滤器注册
        filterRegistration.setFilter(new MyFilter());
        // 过滤器执行URL
        filterRegistration.addUrlPatterns("/*");
        // 注册的名称
        filterRegistration.setName("MyFilter");
        //设置过滤器链执行顺序
        filterRegistration.setOrder(2);
        // 启用注册标志
        filterRegistration.setEnabled(true);

        return filterRegistration;
    }

    /**
     * 注册过滤器
     * <p>此注册方式同等于MyFilter类上使用以下两个注解：</p>
     * <p>@Component</p>
     * <p>@WebFilter(filterName = "myFilter", urlPatterns = "/*")</p>
     *
     * @return 过滤器
     */
    @Bean
    public FilterRegistrationBean<Filter> configRegisterFilter() {
        // 创建一个新的FilterRegistrationBean实例
        FilterRegistrationBean<Filter> filterRegistration = new FilterRegistrationBean<>();

        // 设置过滤器注册
        filterRegistration.setFilter(new ConfigRegisterFilter());
        // 过滤器执行URL
        filterRegistration.addUrlPatterns("/*");
        // 注册的名称
        filterRegistration.setName("ConfigRegisterFilter");
        //设置过滤器链执行顺序
        filterRegistration.setOrder(3);
        // 启用注册标志
        filterRegistration.setEnabled(true);

        return filterRegistration;
    }

    /**
     * 注册防xss攻击、sql注入过滤器
     *
     * @return 过滤器
     */
    @Bean
    public FilterRegistrationBean<XssAndSqlFilter> xssFilterRegistrationBean() {
        FilterRegistrationBean<XssAndSqlFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new XssAndSqlFilter());
        filterRegistrationBean.setOrder(1);
        filterRegistrationBean.setEnabled(true);
        filterRegistrationBean.addUrlPatterns("/*");
        Map<String, String> initParameters = Maps.newHashMap();
        initParameters.put("excludes", "/favicon.ico,/img/*,/js/*,/css/*");
        initParameters.put("isIncludeRichText", "true");
        filterRegistrationBean.setInitParameters(initParameters);
        return filterRegistrationBean;
    }

    /**
     * 注册监听器
     *
     * @return 监听器
     */
    @Bean
    public ServletListenerRegistrationBean<EventListener> registrationBean() {
        ServletListenerRegistrationBean<EventListener> registrationBean = new ServletListenerRegistrationBean<>();
        registrationBean.setListener(new MyHttpRequestListener());
        registrationBean.setListener(new MyHttpSessionListener());
        return registrationBean;
    }
}
